02. Testing and Class Design
Testing and Class Design
ND079 JPND C3 L5 A02 Testing And Class Design V2
Testing Around Dependencies
How do we test UserService.fancyBusiness
without relying on the behavior of SalesService.fizzBuzz?
- Create a custom
SalesService
that does what we tell it to do. - Get the fake
SalesService
intoUserService
so it uses that instead of its normal behavior.
Use Interfaces to Create Fake Services
public interface SalesService {
String fizzBuzz(int i);
}
Creating an interface for Services makes it easy to create fake versions of those Services. This FakeSalesService
returns whatever value was used to create it when fizzBuzz
is called.
public class FakeSalesService implements SalesService {
private String returnValue;
public FakeSalesService(String returnValue) {
this.returnValue = returnValue;
}
@Override
public String fizzBuzz(int i) {
return returnValue;
}
}
Decouple Dependencies
Now that we have an interface, we should update UserService
so that we can replace the SalesService
it uses with the one we want.
public class UserServiceImpl implements UserService {
SalesService salesService;
public UserServiceImpl(SalesService salesService) {
this.salesService = salesService;
}
public String fancyBusiness(int n) {/* hidden */ }
// remainder omitted
}
Test!
We're finally ready to test. This unit test looks for the first requirement:
- If SalesService.fizzBuzz returns “Fizz”, “Buzz”, or “FizzBuzz”, then fancyBusiness just returns that string.
@ParameterizedTest
@ValueSource(strings={"Fizz", "Buzz", "FizzBuzz"})
public void fancyBusinessFakeFizzBuzz_getsFizzBuzzString_returnsSameString(
String returnString) {
SalesService salesService = new FakeSalesService(returnString);
UserService userService = new UserServiceImpl(salesService);
// which number we pass doesn't matter, because we're controlling
// the return value of FizzBuzz
assertEquals(returnString, userService.fancyBusiness(1));
}
This test creates a FakeSalesService
that will always return the string provided from our @ValueSource
. When we call userService.fancyBusiness(1)
, the user service will then call the fizzBuzz
method on the fake sales service. We then use assertEquals
to verify that the fancyBusiness
returns the unmodified string for "Fizz", "Buzz", and "FizzBuzz".